tr parameter (NIL). 42: 3F2C 0058 '?,.X' PUSH 88(A4) iovRefNum parameter. 46: 4EBA 0BAE 1000BF6 JSR FlushVol If a volume is available, flush it. 4A: 3C1F '<.' POP D6 Pop off error code. 4C: 206D FEC8 -$138 lab_3 MOVEA.L glob49(A5),A0 Now do the same thing with the right list box. 50: 2850 '(P' MOVEA.L (A0),A4 52: 4A6C 0058 'Jl.X' TST 88(A4) 56: 670E 1000066 BEQ.S lab_4 58: 4267 'Bg' CLR -(A7) 5A: 42A7 'B.' CLR.L -(A7) 5C: 3F2C 0058 '?,.X' PUSH 88(A4) 60: 4EBA 0B94 1000BF6 JSR FlushVol 64: 3C1F '<.' POP D6 Lets take a quick look and FlushVol and we can see a couple of things. Fist of all, we can quickly see what the parameters are: Parm1 is a pointer to the Volume Name, Parm2 is the Volume Ref Number. Looking back at MainEven, we see that the PEA 88(A4) is referring to the Volume Reference Number. FlushVol "writes the contents of the associated volume buffer and descriptive informatin about the volume (if they've changed since the last time FlushVol was called)." [IM II pg 89]. The returned result of this procedure is the OSErr. ;-refs - 1/MAINEVEN 2/FLUSHRES 2/REMOVEST BF6: 4E56 FFC0 'NV..' FlushVol LINK A6,#-$40 BFA: 41EE FFC0 200FFC0 LEA vbu_1(A6),A0 BFE: 316E 0008 0016 2000008 MOVE param2(A6),ioVRefNum(A0) C04: 216E 000A 0012 200000A MOVE.L param1(A6),ioNamePtr(A0) C0A: A013 '..' _FlushVol ; (A0|IOPB:ParamBlockRec):D0\OSErr C0C: 3D40 000E 200000E MOVE D0,funRslt(A6) C10: 4E5E 'N^' UNLK A6 C12: 225F '"_' POP.L A1 C14: 5C8F '\.' ADDQ.L #6,A7 C16: 4ED1 'N.' JMP (A1) back to MainEven 66: 4EAD 020A 2005DCA lab_4 JSR HANDLEBU(A5) 6A: 486D 0212 2005EF8 PEA MYFILTER(A5) 6E: 486E FFFA 200FFFA PEA vab_1(A6) 72: A991 '..' _ModalDialog ; (filterProc:ProcPtr; VAR itemHit:INTEGER) ModalDialog is the all-purpose dialog handler. It will monitor events and wait for an event involving an active dialog item. Upon returning, the dialog item number is returned in ModalDialog's 2nd parameter - in this case, vab_1. Once the trap returns, the program has to figure out what to do now that an item has been activated. Below, is a simple jump table that repeatedly subtracts integers from vab_1 until it is zero, at which point the program knows that it has the proper dialog item. It then branches to the appropriate routine. ModalDialog also takes a parameter that specifies a special procedure that it can call whenever an event occurs. What that means, is that the line PEA MYFILTER is telling ModalDialog to execute the procedure MYFILTER anytime an event occurs. We can take a look at MYFILTER to see what it is doing (although in cracking, we probably don't care). Right now I will guess that MYFILTER is taking care of things like allowing multiple selections in the list boxes,. displaying the font string, and displaying the size of the selection. 74: 302E FFFA 200FFFA MOVE vab_1(A6),D0 78: 5540 'U@' SUBQ #2,D0 Copy button. 7A: 6736 10000B2 BEQ.S lab_7 7C: 5340 'S@' SUBQ #1,D0 Remove Button. 7E: 672C 10000AC BEQ.S lab_6 80: 5340 'S@' SUBQ #1,D0 Help Button. 82: 6734 10000B8 BEQ.S lab_8 84: 5340 'S@' SUBQ #1,D0 Quit Button. 86: 6720 10000A8 BEQ.S lab_5 88: 5340 'S@' SUBQ #1,D0 Left Open/Close Button. 8A: 673C 10000C8 BEQ.S lab_10 8C: 5340 'S@' SUBQ #1,D0 Right Open/Close Button. 8E: 6742 10000D2 BEQ.S lab_11 90: 5340 'S@' SUBQ #1,D0 Font Radio Button. 92: 672A 10000BE BEQ.S lab_9 94: 5340 'S@' SUBQ #1,D0 DA Radio Button. 96: 6726 10000BE BEQ.S lab_9 98: 5340 'S@' SUBQ #1,D0 Left List Box. 9A: 6740 10000DC BEQ.S lab_12 9C: 5340 'S@' SUBQ #1,D0 Right List Box. 9E: 674A 10000EA BEQ.S lab_13 A0: 0440 0028 '.@.(' SUBI #40,D0 We will have to check MyFilter to see what this is doing. A4: 6752 10000F8 BEQ.S lab_14 A6: 6058 1000100 BRA.S lab_15 A8: 7E01 '~.' lab_5 MOVEQ #1,D7 User hit Quit, so disable the loop and jump to the loop end. AA: 6054 1000100 BRA.S lab_15 AC: 4EAD 01E2 2004E98 lab_6 JSR REMOVEST(A5) Remove Button. B0: 604E 1000100 BRA.S lab_15 B2: 4EAD 01EA 2004F5C lab_7 JSR COPYSTUF(A5) Copy Button. B6: 6048 1000100 BRA.S lab_15 B8: 4EAD 023A 2006B0E lab_8 JSR DOHELP(A5) Help Button. BC: 6042 1000100 BRA.S lab_15 BE: 3F2E FFFA 200FFFA lab_9 PUSH vab_1(A6) Push the selected item number, C2: 4EAD 022A 20064F2 JSR SELCLICK(A5) and change to either Fonts or DAs. C6: 6038 1000100 BRA.S lab_15 C8: 2F2D FEC4 -$13C lab_10 PUSH.L glob48(A5) CC: 4EAD 0242 2006B50 JSR DOCFILE(A5) Left Open (or close) Button. D0: 602E 1000100 BRA.S lab_15 D2: 2F2D FEC8 -$138 lab_11 PUSH.L glob49(A5) D6: 4EAD 0242 2006B50 JSR DOCFILE(A5) Right Open (or close) Button. DA: 6024 1000100 BRA.S lab_15 DC: 2F2D FEC4 -$13C lab_12 PUSH.L glob48(A5) Remember this guy? Refers to the left box. E0: 2F2D FFE8 -$18 PUSH.L glob62(A5) E4: 4EAD 0202 2005CB8 JSR CONTENTC(A5) Handle a list box click. E8: 6016 1000100 BRA.S lab_15 EA: 2F2D FEC8 -$138 lab_13 PUSH.L glob49(A5) Refers to the right list box. EE: 2F2D FFE8 -$18 PUSH.L glob62(A5) F2: 4EAD 0202 2005CB8 JSR CONTENTC(A5) List box handler. F6: 6008 1000100 BRA.S lab_15 F8: 3F2D FEDC -$124 lab_14 PUSH glob55(A5) FC: 4EAD 0232 2006A6A JSR HANDLEIN(A5) 100: 1007 '..' lab_15 MOVE.B D7,D0 Here is the end of the main loop. This checks to see if the loop should terminate. If not, branch back to the beginning of the loop. 102: 6700 FF06 100000A BEQ lab_1 106: 4CDF 10C0 'L...' MOVEM.L (A7)+,D6-D7/A4 At this point, either an error occurred or the user has hit the Quit button. 10A: 4E5E 'N^' UNLK A6 10C: 4E75 'Nu' RTS 10E: CD41 494E 4556 454E data1 DNAME MAINEVEN,0,0 HANDLEBU Procedure 5DCA: QUAL HANDLEBU ; b# =501 s#2 =proc214 vid_1 VEQU -272 vid_2 VEQU -256 5DCA: VEND A quick observation here. After scanning the first few lines, you can notice some hereto unknown things. Look at the references to glob50. At this point, we know that globs 48 and 49 have been set up to refer (we don't know exactly how) to the two list boxes in the main dialog. A quick look down a ways reveals that D7 is used to pass an integer to our DrawString procedure (proc5). If we assume that D7 is the ID # of the STR# resource (since this is the parameter that proc5 requires), then that MOVEQ 1,D7 (line 5) must refer to STR# 1 which reads "Copy". The next two strings in the resource are "<>Copy>>" which are exactly the three strings that the copy button on the dialog can contain. So we might assume right now that glob50 refers to one of the list boxes, and can be used to determine whether the user has selected an item(s) in the list box. Based upon this information, the procedure will fill in the copy button with the proper string. ;-refs - 1/MAINEVEN 5DCA: 4E56 FEEE 'NV..' HANDLEBU LINK A6,#-$112 5DCE: 48E7 0308 'H...' MOVEM.L D6-D7/A4,-(A7) 5DD2: 4AAD FECC -$134 TST.L glob50(A5) Check the list box (it seems) 5DD6: 660C 2005DE4 BNE.S lid_1 Look at what this branch is skipping. 5DD8: 7E01 '~.' MOVEQ #1,D7 The string is "Copy". 5DDA: 3F3C 0003 '?<..' PUSH #3 DIMITEM needs the item number to dim as a parm. Item 3 is the Remove button. 5DDE: 4EBA A308 20000E8 JSR DIMITEM Take a quick look at DIMITEM and you will see that it takes an item number as a parameter, pushes the parameter, then pushes the number -1 (255 if we are talking about signed numbers) and calls HILITEIT which uses the 2nd parameter to either set or dim the desired button. 5DE2: 607A 2005E5E BRA.S lid_8 The Remove button is dimmed anytime there is no selection in one of the list boxes. How did this procedure know there was no selection? It checked to see if glob50 was blank (or possible a NIL pointer) and if so, there is no selection. 5DE4: 202D FECC -$134 lid_1 MOVE.L glob50(A5),D0 Here is the real key. glob50 is being compared to glob48. We know glob48 has something to do with the left list box, and look what happens if they are the same...D7 gets 3 which means string">>Copy>>" - the user has made a selection in the left list box. 5DE8: B0AD FEC4 -$13C CMP.L glob48(A5),D0 5DEC: 6604 2005DF2 BNE.S lid_2 5DEE: 7E03 '~.' MOVEQ #3,D7 5DF0: 6002 2005DF4 BRA.S lid_3 5DF2: 7E02 '~.' lid_2 MOVEQ #2,D7 Otherwise the user has made a selection in the right list box. A quick note: glob50 was not compared to glob49, but it was compared to glob48. We can deduce from this that glob50 had to contain either glob48 or glob49. What this means is that glob50 seems to indicate that something has been selected in one of the list boxes or is empty if there is no selection. 5DF4: 206D FECC -$134 lid_3 MOVEA.L glob50(A5),A0 This is a mess. We know that glob50 is a handle to a host of information about one of the list boxes, but we didn't bother to figure which bytes mean what. The best thing to do here is to analyze all the branches in the mess, see where they go, and look at what happens as a result of each branch. So... 5DF8: 2050 ' P' MOVEA.L (A0),A0 5DFA: 2068 0004 ' h..' MOVEA.L 4(A0),A0 5DFE: 2050 ' P' MOVEA.L (A0),A0 5E00: 3C28 0058 '<(.X' MOVE 88(A0),D6 Look familiar? Let's guess that this is a vRefNum for the list box containing the selection. 5E04: 206D FECC -$134 MOVEA.L glob50(A5),A0 5E08: 2050 ' P' MOVEA.L (A0),A0 5E0A: 2068 0004 ' h..' MOVEA.L 4(A0),A0 5E0E: 2050 ' P' MOVEA.L (A0),A0 5E10: 4A68 0056 'Jh.V' TST 86(A0) 5E14: 6C02 2005E18 BGE.S lid_4 OK, here is a branch. If it executes, D6 has something (which we guessed to be a vRefNum) in it which gets passed on to lid_4. 5E16: 4246 'BF' CLR D6 Otherewise, D6 is zeroed (no volume available). 5E18: 4A46 'JF' lid_4 TST D6 5E1A: 57C0 'W.' SEQ D0 D0=FF hex if there is no volume. 5E1C: 4A00 'J.' TST.B D0 5E1E: 6616 2005E36 BNE.S lid_5 This branch executes if D6 was zero and will cause 1 to moved into D7 - "Copy". 5E20: 2F00 '/.' PUSH.L D0 Save D0 on the stack (not a parameter) 5E22: 4267 'Bg' CLR -(A7) Create space on the stack for the return value. 5E24: 3F06 '?.' PUSH D6 Aha! We were right. proc6 needs a vRefNum and here is good old D6 being pushed as a parm. D6 is indeed the vRefNum. 5E26: 4EAD 0032 10004CA JSR proc6(A5) Takes a vRefNum as a parm, then does a GetVolInfo, and checks the iovAttributes to see if the disk is locked. Returns a 1 if locked, 0 if unlocked. 5E2A: 121F '..' POP.B D1 Pop off the locked status. 5E2C: 201F ' .' POP.L D0 Pop off the original D0. 5E2E: 8001 '..' OR.B D1,D0 Or them so that, in effect, the AND instruction below will be ANDing both D0 and D1 with 1. 5E30: 0240 0001 '.@..' ANDI #1,D0 Check to see if one of the two contains a non-zero value, 5E34: 6702 2005E38 BEQ.S lid_6 and if so, do not put a 1 in D7 (the string is not "Copy"). 5E36: 7E01 '~.' lid_5 MOVEQ #1,D7 String is "Copy" (meaning that DA Mover will not allow the Copy to proceed) and from the above code, we might guess that this is a result of the destination volume being locked so copying is impossible. 5E38: 4267 'Bg' lid_6 CLR -(A7) 5E3A: 206D FECC -$134 MOVEA.L glob50(A5),A0 And here is basically the same as above except that the other list box's volume is being checked 5E3E: 2050 ' P' MOVEA.L (A0),A0 5E40: 3F28 0058 '?(.X' PUSH 88(A0) Push the vRefNum of the volume from which the selection has been made. 5E44: 4EAD 0032 10004CA JSR proc6(A5) Locked Volume? 5E48: 101F '..' POP.B D0 5E4A: 670A 2005E56 BEQ.S lid_7 Go if not locked. 5E4C: 3F3C 0003 '?<..' PUSH #3 If the volume is locked, we cannot remove anything so dim the Remove Button. 5E50: 4EBA A296 20000E8 JSR DIMITEM 5E54: 6008 2005E5E BRA.S lid_8 5E56: 3F3C 0003 '?<..' lid_7 PUSH #3 Else activate the Remove Button (volume is not locked). 5E5A: 4EBA A2AE 200010A JSR UNDIMITE OK, let's re-cap for a minute. If you look back at MakeAWin, you will note that glob48 and glob49 are set up to refer to information about the left and right list boxes respectively. We also know that these globs contain information about the volume (and possibly the file) that is being displayed in the list boxes - since 88 bytes off the start of the pointer is the volume reference number. The above code can be broken into two pieces: from line 5DF4, to lid_5 and from lid_6 to one line past lid_7. The first piece is messy, but the end result is that the destination volume is tested to see if it is locked, and if so, the copy button text is set to "Copy". Therefore we can now assume that all that messy stuff beforehand was in essence setting a pointer to the destination list box information. Remember from MakeAWin there was a strange section of code that seemed to link the two globs to each other? Well, now we see that glob50 is set to one of these two (the one that contains a selection) but glob50 must also be able to access the other list box's volume to see if it is locked (or to see if copying to it is possible). The second section checks to see if the volume containing the selection is locked, and if so, Removing is not possible. 5E5E: BE6D FFF4 -$C lid_8 CMP.W glob65(A5),D7 Once again, we don't know what this glob means, but we can see what gets skipped if the branch executes. Once we know what gets skipped, we have a decent idea what the global means. Keep in mind that the global is being compared to D7 - the string resource ID #. 5E62: 6700 0082 2005EE6 BEQ lid_13 So if glob65 contains the ID # in D7, skip to the end of the procedure. 5E66: 42A7 'B.' CLR.L -(A7) 5E68: A8D8 '..' _NewRgn ; :RgnHandle 5E6A: 285F '(_' POP.L A4 5E6C: 2F0C '/.' PUSH.L A4 5E6E: A87A '.z' _GetClip ; (rgn:RgnHandle) 5E70: 486E FEF0 200FEF0 PEA vid_1(A6) 5E74: 42A7 'B.' CLR.L -(A7) 5E76: 42A7 'B.' CLR.L -(A7) 5E78: A8A7 '..' _SetRect ; (VAR r:Rect; left,top,right,bottom:INTEGER) 5E7A: 486E FEF0 200FEF0 PEA vid_1(A6) 5E7E: A87B '.{' _ClipRect ; (r:Rect) 5E80: 486E FF00 200FF00 PEA vid_2(A6) 5E84: 3F07 '?.' PUSH D7 5E86: 4EAD 002A 100048C JSR proc5(A5) Once again, the DrawString procedure. D7 is the string # and vid_2 returns a pointer to the string. 5E8A: 2F2D FFF6 -$A PUSH.L glob66(A5) Look at the trap below. glob66 HAS to be a CtlHdl (Handle to a control object on a dialog), 5E8E: 486E FF00 200FF00 PEA vid_2(A6) and vid_2 we already know has the string whose ID # is in D7. Since D7's string is "Copy", ">>Copy>>", or "<